package system

import (
	"cubeAdmin/common"
	"cubeAdmin/common/jwtauth"
	"cubeAdmin/common/utils"
	"cubeAdmin/controllers"
	"cubeAdmin/dto"
	"cubeAdmin/models"
	"cubeAdmin/vo"
	"encoding/base64"
	"fmt"
	"github.com/beego/beego/v2/core/logs"
	"github.com/mojocn/base64Captcha"
	"github.com/mssola/user_agent"
	"image/color"
	"strconv"
	"strings"
	"time"
)

// LoginController 登录api
type LoginController struct {
	controllers.BaseController
}

type CaptchaResult struct {
	Id          string `json:"id"`
	Base64Blob  string `json:"base_64_blob"`
	VerifyValue string `json:"code"`
}

// 设置自带的store
var store = base64Captcha.DefaultMemStore

func (c *LoginController) URLMapping() {
	c.Mapping("Login", c.Login)
	c.Mapping("Captcha", c.Captcha)
	c.Mapping("Info", c.Info)
	c.Mapping("Logout", c.Logout)
}

// 登录 TODO:XSRF过滤
func (c *LoginController) LoginIn() {
	//if c.UserId > 0 {
	//	urlFor := beego.URLFor("HomeController.Index")
	//	c.Redirect(urlFor,200)
	//}
	c.TplName = "login.tpl"
}

// Login @Title 登录
// @Description 登录
// @Param	code	query	string	true	"验证码"
// @Param	password	query	string	true	"密码"
// @Param	username	query	string	true	"用户名"
// @Success 200 {object} controllers.Result
// @router /login [post]
func (c *LoginController) Login() {
	var authUser dto.AuthUser

	err := c.ParseForm(&authUser)
	if err != nil {
		c.Fail(err.Error(), common.ParseFormErr)
	}
	logs.Debug(authUser)
	if err == nil {
		currentUser, e := models.GetUserByUsername(authUser.Username)
		if e != nil {
			c.Fail("用户不存在", common.DatabaseOperationErr)
		}

		captchaId := c.GetSession("captchaId")
		//校验验证码
		if !store.Verify(captchaId.(string), authUser.Code, true) {
			c.Fail("验证码不对", common.ArgsValidErr)
		}
		logs.Debug("=======currentUser======")
		logs.Debug(currentUser)
		if !utils.ComparePwd(currentUser.Password, []byte(authUser.Password)) {
			c.Fail("密码错误", common.ArgsValidErr)
		} else {
			token, _ := jwtauth.GenerateToken(currentUser, time.Minute*30)
			var loginVO = new(vo.LoginVo)
			loginVO.Token = token
			loginVO.User = currentUser
			e := c.SetSession("user", currentUser)
			if e != nil {
				c.Fail(err.Error(), common.MsgErr)
			}
			c.Ctx.SetCookie("token", "Bearer "+token)

			defer func() {
				valInt64, err := strconv.ParseInt(authUser.Id, 10, 64)
				if err != nil {
					logs.Error("convert string to int failed, err:", err)
				}
				LoginLogToDB(c, strconv.Itoa(common.MsgOk), "登录成功", valInt64, authUser.Username)
			}()

			c.Ok(loginVO)
		}
	} else {
		c.Fail(err.Error(), common.MsgErr)
	}
}

// Info @Title 获取用户信息
// @Description 获取用户信息
// @Param	token	query	string	true	"请求头"
// @Success 200 {object} dada.Result
// @Failure 401 没有认证
// @Failure 500 服务异常
// @Failure 404 User not found
// @router /info [get]
func (c *LoginController) Info() {
	user, _ := jwtauth.GetAdminDetailUser(c.Ctx.Input)
	c.Ok(user)
}

// Logout
// @Title 退出登录
// @Description 退出登录
// @Success 200 {object} controllers.Result
// @router /logout [delete]
func (c *LoginController) Logout() {
	err := jwtauth.RemoveUser(c.Ctx.Input)
	if err != nil {
		c.Fail("退出失败", common.MsgErr)
	} else {
		c.DelSession("user")
		c.Ok("退出成功")
	}
}

// Captcha
// @Title 获取验证码
// @Description 获取验证码
// @Success 200 {object} string
// @router /captcha [get]
func (c *LoginController) Captcha() {
	captcha := GenerateCaptcha()
	c.SetSession("captchaId", captcha.Id)
	data, _ := base64.StdEncoding.DecodeString(strings.Split(captcha.Base64Blob, "base64,")[1])
	c.Ctx.Output.Header("Content-Type", "image/jpg")
	c.Ctx.WriteString(string(data))
	fmt.Println(captcha.Base64Blob)
}

// GenerateCaptcha 生成图形化验证码
func GenerateCaptcha() CaptchaResult {
	var driver base64Captcha.Driver
	var driverString base64Captcha.DriverMath

	// 配置验证码信息
	captchaConfig := base64Captcha.DriverMath{
		Height:          38,
		Width:           110,
		NoiseCount:      0,
		ShowLineOptions: 0,
		BgColor: &color.RGBA{
			R: 3,
			G: 102,
			B: 214,
			A: 125,
		},
		Fonts: []string{"wqy-microhei.ttc"},
	}

	// 自定义配置，如果不需要自定义配置，则上面的结构体和下面这行代码不用写
	driverString = captchaConfig
	driver = driverString.ConvertFonts()

	captcha := base64Captcha.NewCaptcha(driver, store)
	id, b64s, err := captcha.Generate()
	if err != nil {
		logs.Error(err.Error())
	}
	captchaResult := CaptchaResult{
		Id:         id,
		Base64Blob: b64s,
	}

	//ctx.Output.JSON(controllers.SuccessData(captchaResult),true,true)
	//ctx.WriteString(captchaResult.Base64Blob)
	return captchaResult
}

// LoginLogToDB 插入登录日志
func LoginLogToDB(c *LoginController, status string, msg string, id int64, username string) {
	ua := user_agent.New(c.Ctx.Request.UserAgent())
	//addr := c.Ctx.Request.RemoteAddr // "IP:port" "192.168.1.150:8889"
	ip := utils.GetClientIP(c.Ctx)
	browserName, browserVersion := ua.Browser()
	s := &models.SysLoginLog{
		Username:      username,
		Status:        status,
		Ipaddr:        ip,
		LoginLocation: "",
		Browser:       browserName + " " + browserVersion,
		Os:            ua.OS(),
		Platform:      ua.Platform(),
		LoginTime:     time.Now(),
		Remark:        c.Ctx.Request.UserAgent(),
		Msg:           msg,
		CreatedAt:     time.Now(),
		UpdatedAt:     time.Now(),
		CreateBy:      id,
		UpdateBy:      id,
	}
	_, err := models.AddSysLoginLog(s)

	if err != nil {
		logs.Error("保存登录日志报错,", err.Error())
		//日志报错错误，不中断请求
	}
}
